package fr.inserm.u915.organifooyi.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Collection;
import java.util.Date;
import java.util.Set;
import java.util.TreeSet;

import fr.inserm.u915.organifooyi.lang.Cast;

public class HistoryTable
	{
	private List<String> headers=new ArrayList<String>();
	private List<Row> rows=new ArrayList<HistoryTable.Row>();
	private Collection<History> histories;
	
	

	
	public class Row
		{
		public class Cell
			{
			private String header;
			private History history=null;
			private int column;
			public Cell(int column,String header)
				{
				this.column=column;
				this.header=header;
				}
			@Override
			public String toString()
				{
				return getValue(); 
				}
			
			public String getPrev()
				{
				if(Row.this.prev!=null)
					{
					return Row.this.prev.getCells().get(this.column).getValue();
					}
				return null;
				}
			
			public String getValue()
				{
				if(history==null)
					{
					return getPrev();
					}
				return history.getNewLiteral();
				}
			public Double getDiff()
				{
				Double curr= Cast.cast(getValue(), Double.class);
				Double prev= Cast.cast(getPrev(), Double.class);
				if(curr==null || prev==null) return null;
				return curr-prev;
				}
			
			}
		
		private Date date;
		private Row prev=null;
		private List<Cell> cells;
		
		public Row(Date date)
			{
			this.date= date;
			this.cells=new ArrayList<Cell>();
			int index=0;
			for(String header:HistoryTable.this.headers)
				{
				Cell c=new Cell(index,header);
				index++;
				this.cells.add(c);
				
				for(History h:HistoryTable.this.histories)
					{
					if(!h.getCreation().equals(this.date)) continue;
					if(!h.getFieldName().equals(c.header)) continue;
					c.history=h;
					break;	
					}
				
				}
			
			}
		public List<Cell> getCells()
			{
			return this.cells;
			}
		public Date getDate()
			{
			return date;
			}
		
		public User getUser()
			{
			for(Cell cell:this.cells) if(cell.history!=null) return cell.history.getCreatedBy();
			return null;
			}
		}
	
	public HistoryTable(Collection<History> histories)
		{
		this.histories=histories;
		Set<String> distinctHeaders=new TreeSet<String>();
		Set<Date> dates=new HashSet<Date>();
		for(History history:histories)
			{
			distinctHeaders.add(history.getFieldName());
			dates.add(history.getCreation());
			}
		
		this.headers.addAll(distinctHeaders);
	
		for(Date d:dates)
			{
			this.rows.add(new Row(d));
			}
		
		
		Collections.sort(this.rows,new Comparator<Row>()
			{
			@Override
			public int compare(Row o1, Row o2) {
				return o2.date.compareTo(o1.date);//inverse
				}
			});
		for(int i=0;i+1< this.rows.size();++i)
			{
			this.rows.get(i).prev=this.rows.get(i+1);
			}
		}
	
	public List<String> getHeaders()
		{
		return this.headers;
		}
	
	public List<Row> getRows() {
		return rows;
		}
	}
